//package reflex.javassist;
//
//import com.alibaba.fastjson.JSON;
//import javassist.ClassPool;
//import javassist.CtClass;
//import javassist.CtMethod;
//import javassist.bytecode.AccessFlag;
//import javassist.bytecode.CodeAttribute;
//import javassist.bytecode.LocalVariableAttribute;
//import javassist.bytecode.MethodInfo;
//import lombok.Data;
//import lombok.experimental.Accessors;
//
//import java.util.List;
//import java.util.concurrent.atomic.AtomicInteger;
//import java.util.concurrent.atomic.AtomicReferenceArray;
//
///**
// * 应用监控
// *
// * @author: zhanglu
// * @date: 2023/7/18 09:57
// * @modify: 修改人信息, 修改内容 2023/7/18 09:57
// */
//public class ApplicationMonitor {
//
//    public static void main(String[] args) {
//        ClassPool pool = ClassPool.getDefault();
//        // 获取类
//        CtClass ctClass = pool.get(ApplicationMonitor.class.getName());
//        CtMethod ctMethod = ctClass.getDeclaredMethod("strToInt");
//        MethodInfo methodInfo = ctMethod.getMethodInfo();
//        boolean isStatic = (methodInfo.getAccessFlags() & AccessFlag.STATIC) != 0;
//        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
//        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
//        CtClass[] parameterTypes = ctMethod.getParameterTypes();
//        // 方法：生成方法唯一标识ID
//        int idx = ApplicationMonitor.generateMethodId(clazzName, methodName, parameterNameList, parameterTypeList, returnTypeName);
//
//
//        // 定义属性
//        ctMethod.addLocalVariable("startNanos", CtClass.longType);
//        // 方法前加强
//        ctMethod.insertBefore("{ startNanos = System.nanoTime(); }");
//        // 定义属性
//        ctMethod.addLocalVariable("parameterValues", pool.get(Object[].class.getName()));
//        // 方法前加强
//        ctMethod.insertBefore("{ parameterValues = new Object[]{" + parameters.toString() + "}; }");
//        // 方法后加强
//        ctMethod.insertAfter("{ reflex.javassist.ApplicationMonitor.point(" + idx + ", startNanos, parameterValues, $_);}", false); // 如果返回类型非对象类型，$_ 需要进行类型转换
//        // 方法；添加TryCatch
//        ctMethod.addCatch("{ reflex.javassist.ApplicationMonitor.point(" + idx + ", $e); throw $e; }", ClassPool.getDefault().get("java.lang.Exception"));   // 添加异常捕获
//
//    }
//
//    public Integer strToInt(String str01, String str02) {
//        return Integer.parseInt(str01);
//    }
//
//    public static final int MAX_NUM = 1024 * 32;
//    private final static AtomicInteger index = new AtomicInteger(0);
//    private final static AtomicReferenceArray<MethodDescription> methodTagArr = new AtomicReferenceArray<>(MAX_NUM);
//
//    public static int generateMethodId(String clazzName, String methodName, List<String> parameterNameList, List<String> parameterTypeList, String returnType) {
//        MethodDescription methodDescription = new MethodDescription();
//        methodDescription.setClazzName(clazzName);
//        methodDescription.setMethodName(methodName);
//        methodDescription.setParameterNameList(parameterNameList);
//        methodDescription.setParameterTypeList(parameterTypeList);
//        methodDescription.setReturnType(returnType);
//        int methodId = index.getAndIncrement();
//        if (methodId > MAX_NUM) return -1;
//        methodTagArr.set(methodId, methodDescription);
//        return methodId;
//    }
//
//    public static void point(final int methodId, final long startNanos, Object[] parameterValues, Object returnValues) {
//        MethodDescription method = methodTagArr.get(methodId);
//        System.out.println("监控 - Begin");
//        System.out.println("方法：" + method.getClazzName() + "." + method.getMethodName());
//        System.out.println("入参：" + JSON.toJSONString(method.getParameterNameList()) + " 入参[类型]：" + JSON.toJSONString(method.getParameterTypeList()) + " 入数[值]：" + JSON.toJSONString(parameterValues));
//        System.out.println("出参：" + method.getReturnType() + " 出参[值]：" + JSON.toJSONString(returnValues));
//        System.out.println("耗时：" + (System.nanoTime() - startNanos) / 1000000 + "(s)");
//        System.out.println("监控 - End\r\n");
//    }
//
//    public static void point(final int methodId, Throwable throwable) {
//        MethodDescription method = methodTagArr.get(methodId);
//        System.out.println("监控 - Begin");
//        System.out.println("方法：" + method.getClazzName() + "." + method.getMethodName());
//        System.out.println("异常：" + throwable.getMessage());
//        System.out.println("监控 - End\r\n");
//    }
//
//
//    @Data
//    @Accessors(chain = true)
//    public static class MethodDescription{
//        private String clazzName;
//        private String methodName;
//        private List<String> parameterNameList;
//        private List<String> parameterTypeList;
//        private String returnType;
//    }
//
//
//}
